<cfcomponent name="UserAgent" hint="Act like a web browser" namespace="org.rickosborne.util">
	<cffunction name="init" returntype="UserAgent" access="public">
		<cfset this.Cookies=QueryNew("Key,Value")>
		<cfset this.UserAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)">
		<cfset this.Timeout=30>
		<cfset this.LastError="">
		<cfreturn this>
	</cffunction>
	<cffunction name="Fetch" returntype="string" access="public" output="true">
		<cfargument name="Method" type="string" required="true">
		<cfargument name="URL" type="string" required="true">
		<cfargument name="Fields" type="struct" required="false">
		<cfargument name="Headers" type="struct" required="false">
		<cfset var i=0>
		<cfset var Result="">
		<cftry>
			<cfhttp method="#Arguments.Method#" url="#Arguments.URL#" useragent="#this.UserAgent#" timeout="#this.Timeout#">
				<cfif StructKeyExists(Arguments,"Headers")>
					<cfloop collection="#Arguments.Headers#" item="i">
						<cfhttpparam type="header" name="#i#" value="#Arguments.Headers[i]#">
					</cfloop>
				</cfif>
				<cfif this.Cookies.RecordCount GT 0>
					<cfhttpparam type="header" name="Cookie" value="#CookiesAsString()#">
				</cfif>
				<cfif StructKeyExists(Arguments,"Fields")>
					<cfloop collection="#Arguments.Fields#" item="i">
						<cfhttpparam type="formfield" name="#i#" value="#Arguments.Fields[i]#">
					</cfloop>
				</cfif>
			</cfhttp>
			<cfset Result=CFHttp.FileContent>
			<cfcatch>
				<cfset this.LastError=CFCatch.Message>
			</cfcatch>
		</cftry>
		<cfreturn Result>
	</cffunction>
	<cffunction name="CookiesAsString" returntype="string" access="public">
		<cfset var Result="">
		<cfloop query="this.Cookies">
			<cfset Result=ListAppend(Result,Key & "=" & Value & ";", " ")>
		</cfloop>
		<cfreturn Result>
	</cffunction>
	<cffunction name="GetLastError" returntype="string" access="public">
		<cfargument name="Reset" type="boolean" required="false" default="false">
		<cfset var Result=this.LastError>
		<cfif Arguments.Reset><cfset this.LastError=""></cfif>
		<cfreturn Result>
	</cffunction>
	<cffunction name="TableToArrays" returntype="array" access="public">
		<cfargument name="Corpus" type="string" required="true">
		<cfset var Result=GetTagContent(Arguments.Corpus,"tr")>
		<cfset var i=0>
		<cfloop index="i" from="#ArrayLen(Result)#" to="1" step="-1">
			<cfset Result[i]=GetTagContent(Result[i],"td")>
			<cfif ArrayLen(Result[i]) EQ 0>
				<cfset ArrayDeleteAt(Result,i)>
			</cfif>
		</cfloop>
		<cfreturn Result>
	</cffunction>
	<cffunction name="GetTagContent" returntype="array" access="public">
		<cfargument name="Corpus" type="string" required="true">
		<cfargument name="Tag" type="string" required="true">
		<cfset var Result=ArrayNew(1)>
		<cfset var c=Arguments.Corpus>
		<cfset var t=Arguments.Tag>
		<cfset var tr=REFindNoCase("<" & t,c,1,false)>
		<cfset var rt=0>
		<cfset var etr=0>
		<cfloop condition="tr GT 0">
			<cfset rt=Find(">",c,tr)>
			<cfset etr=REFindNoCase("</" & t,c,tr,false)>
			<cfif (rt GT tr) AND (etr GT rt)>
				<cfif etr GT (rt + 1)>
					<cfset ArrayAppend(Result,Trim(Mid(c,rt+1,etr-rt-1)))>
				<cfelse>
					<cfset ArrayAppend(Result,"")>
				</cfif>
				<cfset tr=REFindNoCase("<" & t,c,etr+1,false)>
			<cfelse>
				<cfset tr=0>
			</cfif>
		</cfloop>
		<cfreturn Result>
	</cffunction>
</cfcomponent>